🧠 Final Model Summary – Predicting Full Type Combinations¶
We extended our original classification task to predict a Pokémon’s full typing combination (e.g. Water/Flying, Fire/) as a single multiclass label, combining both primary and secondary types.
📁 Dataset Overview¶
- Kaggle Pokemon Database: https://www.kaggle.com/datasets/mrdew25/pokemon-database
- Total Pokémon used:
1,382including alternate forms, or1,054base forms only - Target variable:
type_combo(combined primary and secondary type)- Multiclass with 113 unique combinations (after filtering low-frequency classes)
🧪 Features Used¶
- Total:
858after preprocessing - Raw stats:
Health,Attack,Defense,Sp. Attack,Sp. Defense,Speed - Composite stat:
Base Stat Total - Normalized stats (each stat as a % of total):
(Base Stat / Base Stat Total) * 100 - Categorical traits:
Primary/Secondary Egg Groups,Primary Ability,Classification - Boolean flag:
is_pre_evolution(whether the Pokémon has a pre-evo)
✅ Model Comparison¶
| Model | Kappa Score | Notes |
|---|---|---|
MLPClassifier |
0.570 | Performed well on most combos; improved with alternate forms |
RandomForest |
0.542 | Slightly worse; gets worse with alternate forms |
🔍 Key Observations¶
- Including alternate forms helped MLP significantly (similar to single-type task)
- For both models, type prediction becomes harder when combining primary + secondary into one target
- Abilities remained top features for MLP, while RF leaned on stat-based signals
🎯 Summary¶
- Predicting full typing is a harder multiclass task than single-type prediction (go figure)
- MLP still leads, though the gap between RF and MLP narrowed in this setup
- Alternate forms provide valuable signal and improve performance consistency
/var/folders/ht/dp3tdfgs34g1r1j0jdjb1qq40000gn/T/ipykernel_28764/4116125279.py:13: FutureWarning: DataFrame.applymap has been deprecated. Use DataFrame.map instead.
df = df.applymap(lambda x: x.strip('"') if isinstance(x, str) else x)
Unique type combinations: 174
Test set size: 267
Classification Report:
precision recall f1-score support
Bug/ 0.33 0.60 0.43 5
Bug/Electric 1.00 1.00 1.00 1
Bug/Fighting 0.00 0.00 0.00 1
Bug/Flying 1.00 0.86 0.92 7
Bug/Grass 0.00 0.00 0.00 1
Bug/Poison 0.33 0.50 0.40 2
Bug/Psychic 1.00 1.00 1.00 1
Bug/Rock 0.00 0.00 0.00 1
Bug/Steel 0.00 0.00 0.00 1
Bug/Water 0.00 0.00 0.00 1
Dark/ 0.40 0.67 0.50 3
Dark/Dragon 1.00 1.00 1.00 1
Dark/Fairy 1.00 1.00 1.00 1
Dark/Fire 0.50 1.00 0.67 1
Dark/Flying 0.00 0.00 0.00 1
Dark/Grass 0.00 0.00 0.00 1
Dark/Ice 0.00 0.00 0.00 1
Dark/Normal 1.00 1.00 1.00 1
Dark/Poison 0.00 0.00 0.00 1
Dark/Steel 1.00 1.00 1.00 1
Dragon/ 1.00 0.33 0.50 3
Dragon/Flying 0.00 0.00 0.00 1
Dragon/Ghost 1.00 1.00 1.00 1
Dragon/Ground 0.00 0.00 0.00 1
Dragon/Ice 0.50 1.00 0.67 1
Dragon/Psychic 1.00 1.00 1.00 1
Dragon/Water 1.00 1.00 1.00 1
Electric/ 0.56 0.62 0.59 8
Electric/Dragon 0.00 0.00 0.00 1
Electric/Flying 0.00 0.00 0.00 2
Electric/Grass 0.00 0.00 0.00 1
Electric/Poison 0.00 0.00 0.00 1
Electric/Steel 1.00 1.00 1.00 1
Fairy/ 0.83 0.56 0.67 9
Fairy/Flying 0.00 0.00 0.00 1
Fairy/Steel 0.00 0.00 0.00 1
Fighting/ 1.00 0.67 0.80 6
Fighting/Dark 0.00 0.00 0.00 1
Fighting/Psychic 1.00 1.00 1.00 1
Fighting/Steel 0.00 0.00 0.00 1
Fighting/Water 0.33 1.00 0.50 1
Fire/ 0.50 0.62 0.56 8
Fire/Bug 1.00 1.00 1.00 1
Fire/Dragon 0.00 0.00 0.00 1
Fire/Fighting 0.00 0.00 0.00 1
Fire/Flying 0.00 0.00 0.00 2
Fire/Ghost 1.00 1.00 1.00 1
Fire/Ground 1.00 1.00 1.00 1
Fire/Psychic 0.00 0.00 0.00 1
Fire/Rock 0.00 0.00 0.00 1
Flying/ 0.00 0.00 0.00 1
Ghost/ 0.43 0.75 0.55 4
Ghost/Fire 0.50 1.00 0.67 1
Ghost/Flying 1.00 1.00 1.00 1
Ghost/Grass 1.00 0.50 0.67 2
Ghost/Poison 0.50 1.00 0.67 1
Grass/ 0.60 0.60 0.60 10
Grass/Dark 0.00 0.00 0.00 1
Grass/Dragon 0.00 0.00 0.00 2
Grass/Fairy 0.00 0.00 0.00 1
Grass/Fighting 0.00 0.00 0.00 1
Grass/Flying 0.50 1.00 0.67 1
Grass/Ghost 1.00 1.00 1.00 1
Grass/Ice 1.00 1.00 1.00 1
Grass/Normal 1.00 1.00 1.00 1
Grass/Poison 0.33 0.33 0.33 3
Grass/Psychic 0.00 0.00 0.00 1
Grass/Steel 0.00 0.00 0.00 1
Ground/ 0.38 0.75 0.50 4
Ground/Dark 1.00 1.00 1.00 1
Ground/Flying 0.00 0.00 0.00 1
Ground/Ghost 0.00 0.00 0.00 1
Ground/Grass 0.00 0.00 0.00 1
Ground/Normal 0.50 1.00 0.67 1
Ground/Rock 0.00 0.00 0.00 1
Ground/Steel 0.00 0.00 0.00 1
Ice/ 0.80 0.80 0.80 5
Ice/Bug 0.00 0.00 0.00 1
Ice/Ground 0.00 0.00 0.00 1
Ice/Psychic 0.00 0.00 0.00 1
Ice/Water 1.00 1.00 1.00 1
Normal/ 0.58 0.74 0.65 19
Normal/Fairy 0.00 0.00 0.00 1
Normal/Fighting 0.00 0.00 0.00 1
Normal/Flying 0.80 0.67 0.73 6
Normal/Grass 1.00 1.00 1.00 2
Normal/Psychic 0.00 0.00 0.00 1
Poison/ 0.57 1.00 0.73 4
Poison/Dark 0.50 1.00 0.67 1
Poison/Dragon 0.00 0.00 0.00 1
Poison/Fighting 1.00 1.00 1.00 1
Poison/Flying 1.00 1.00 1.00 1
Poison/Ground 0.00 0.00 0.00 1
Poison/Psychic 0.00 0.00 0.00 1
Poison/Water 0.00 0.00 0.00 1
Psychic/ 0.75 0.60 0.67 15
Psychic/Fairy 0.67 1.00 0.80 2
Psychic/Flying 0.00 0.00 0.00 2
Psychic/Ghost 0.00 0.00 0.00 1
Psychic/Steel 0.00 0.00 0.00 1
Rock/ 0.75 0.75 0.75 4
Rock/Electric 1.00 1.00 1.00 1
Rock/Fairy 0.50 1.00 0.67 1
Rock/Fire 0.00 0.00 0.00 1
Rock/Flying 1.00 1.00 1.00 2
Rock/Ground 0.50 1.00 0.67 1
Rock/Ice 0.00 0.00 0.00 1
Rock/Poison 0.00 0.00 0.00 1
Rock/Psychic 0.00 0.00 0.00 1
Rock/Steel 0.50 1.00 0.67 1
Rock/Water 1.00 1.00 1.00 1
Steel/ 0.60 1.00 0.75 3
Steel/Dragon 0.67 1.00 0.80 2
Steel/Fairy 0.50 1.00 0.67 1
Steel/Ghost 1.00 1.00 1.00 1
Steel/Ground 0.00 0.00 0.00 1
Steel/Psychic 0.50 0.50 0.50 2
Steel/Rock 1.00 1.00 1.00 1
Water/ 0.76 0.76 0.76 17
Water/Dark 0.50 0.50 0.50 2
Water/Dragon 0.50 1.00 0.67 1
Water/Fairy 0.00 0.00 0.00 1
Water/Fighting 0.00 0.00 0.00 1
Water/Flying 0.50 1.00 0.67 1
Water/Ghost 0.00 0.00 0.00 1
Water/Grass 0.50 1.00 0.67 1
Water/Ground 1.00 1.00 1.00 2
Water/Ice 0.00 0.00 0.00 1
Water/Poison 0.50 1.00 0.67 1
Water/Psychic 0.00 0.00 0.00 1
Water/Rock 1.00 1.00 1.00 1
micro avg 0.60 0.58 0.59 267
macro avg 0.42 0.49 0.43 267
weighted avg 0.54 0.58 0.54 267
Cohen's Kappa Score: 0.570
/Users/rohanhangal/PersonalProjects/data_engineering/pokemon_project/venv/lib/python3.13/site-packages/sklearn/metrics/_classification.py:1565: UndefinedMetricWarning: Precision is ill-defined and being set to 0.0 in labels with no predicted samples. Use `zero_division` parameter to control this behavior.
_warn_prf(average, modifier, f"{metric.capitalize()} is", len(result))
/Users/rohanhangal/PersonalProjects/data_engineering/pokemon_project/venv/lib/python3.13/site-packages/sklearn/metrics/_classification.py:1565: UndefinedMetricWarning: Precision is ill-defined and being set to 0.0 in labels with no predicted samples. Use `zero_division` parameter to control this behavior.
_warn_prf(average, modifier, f"{metric.capitalize()} is", len(result))
/Users/rohanhangal/PersonalProjects/data_engineering/pokemon_project/venv/lib/python3.13/site-packages/sklearn/metrics/_classification.py:1565: UndefinedMetricWarning: Precision is ill-defined and being set to 0.0 in labels with no predicted samples. Use `zero_division` parameter to control this behavior.
_warn_prf(average, modifier, f"{metric.capitalize()} is", len(result))
✅ Model - RF¶
/var/folders/ht/dp3tdfgs34g1r1j0jdjb1qq40000gn/T/ipykernel_28764/443486346.py:13: FutureWarning: DataFrame.applymap has been deprecated. Use DataFrame.map instead.
df = df.applymap(lambda x: x.strip('"') if isinstance(x, str) else x)
Unique type combinations: 149
Test set size: 200
precision recall f1-score support
Bug/ 0.30 0.60 0.40 5
Bug/Electric 1.00 1.00 1.00 1
Bug/Fighting 0.00 0.00 0.00 1
Bug/Flying 0.75 1.00 0.86 3
Bug/Grass 0.00 0.00 0.00 1
Bug/Poison 1.00 0.50 0.67 2
Bug/Psychic 0.00 0.00 0.00 1
Bug/Rock 0.00 0.00 0.00 1
Bug/Steel 0.00 0.00 0.00 1
Bug/Water 0.00 0.00 0.00 1
Dark/ 0.00 0.00 0.00 3
Dark/Dragon 0.00 0.00 0.00 1
Dark/Fairy 1.00 1.00 1.00 1
Dark/Fire 0.00 0.00 0.00 1
Dark/Flying 0.00 0.00 0.00 1
Dark/Ice 0.00 0.00 0.00 1
Dark/Steel 0.00 0.00 0.00 1
Dragon/ 0.60 1.00 0.75 3
Dragon/Flying 0.00 0.00 0.00 1
Dragon/Ghost 1.00 1.00 1.00 1
Dragon/Ground 1.00 1.00 1.00 1
Dragon/Ice 0.00 0.00 0.00 1
Electric/ 0.50 0.62 0.56 8
Electric/Dragon 0.00 0.00 0.00 1
Electric/Flying 0.00 0.00 0.00 1
Electric/Steel 0.50 1.00 0.67 1
Fairy/ 0.43 0.60 0.50 5
Fairy/Flying 0.00 0.00 0.00 1
Fairy/Steel 1.00 1.00 1.00 1
Fighting/ 0.75 0.50 0.60 6
Fighting/Dark 1.00 1.00 1.00 1
Fire/ 0.75 0.86 0.80 7
Fire/Fighting 0.00 0.00 0.00 1
Fire/Flying 0.00 0.00 0.00 1
Fire/Ghost 0.00 0.00 0.00 1
Flying/ 0.00 0.00 0.00 1
Ghost/ 0.67 0.67 0.67 3
Ghost/Fire 0.00 0.00 0.00 1
Ghost/Grass 0.00 0.00 0.00 1
Ghost/Poison 1.00 1.00 1.00 1
Grass/ 0.67 0.80 0.73 10
Grass/Dark 0.00 0.00 0.00 1
Grass/Dragon 1.00 1.00 1.00 1
Grass/Fairy 0.50 1.00 0.67 1
Grass/Fighting 0.00 0.00 0.00 1
Grass/Flying 1.00 1.00 1.00 1
Grass/Ghost 0.00 0.00 0.00 1
Grass/Normal 0.00 0.00 0.00 1
Grass/Poison 0.50 0.67 0.57 3
Grass/Psychic 1.00 1.00 1.00 1
Grass/Steel 1.00 1.00 1.00 1
Ground/ 1.00 0.50 0.67 4
Ground/Dark 0.00 0.00 0.00 1
Ground/Flying 1.00 1.00 1.00 1
Ground/Ghost 1.00 1.00 1.00 1
Ground/Rock 1.00 1.00 1.00 1
Ice/ 0.75 1.00 0.86 3
Ice/Ground 0.00 0.00 0.00 1
Ice/Psychic 0.00 0.00 0.00 1
Ice/Water 0.00 0.00 0.00 1
Normal/ 0.43 1.00 0.60 15
Normal/Fairy 0.00 0.00 0.00 1
Normal/Flying 0.56 1.00 0.71 5
Normal/Psychic 0.00 0.00 0.00 1
Poison/ 0.50 0.33 0.40 3
Poison/Dark 0.00 0.00 0.00 1
Poison/Dragon 0.00 0.00 0.00 1
Poison/Fighting 0.00 0.00 0.00 1
Poison/Flying 1.00 1.00 1.00 1
Poison/Ground 0.00 0.00 0.00 1
Poison/Normal 0.00 0.00 0.00 1
Poison/Water 0.00 0.00 0.00 1
Psychic/ 0.40 0.75 0.52 8
Psychic/Fairy 0.00 0.00 0.00 1
Psychic/Flying 0.00 0.00 0.00 1
Psychic/Ghost 1.00 1.00 1.00 1
Psychic/Steel 1.00 1.00 1.00 1
Rock/ 1.00 1.00 1.00 3
Rock/Fairy 0.00 0.00 0.00 1
Rock/Flying 0.00 0.00 0.00 1
Rock/Ground 1.00 1.00 1.00 1
Rock/Poison 0.00 0.00 0.00 1
Rock/Psychic 0.00 0.00 0.00 1
Rock/Steel 0.50 1.00 0.67 1
Rock/Water 0.00 0.00 0.00 1
Steel/ 1.00 0.50 0.67 2
Steel/Dragon 0.00 0.00 0.00 1
Steel/Fairy 0.00 0.00 0.00 1
Steel/Ghost 0.00 0.00 0.00 1
Steel/Psychic 0.00 0.00 0.00 1
Steel/Rock 1.00 1.00 1.00 1
Water/ 0.57 0.87 0.68 15
Water/Dark 0.00 0.00 0.00 1
Water/Dragon 0.00 0.00 0.00 1
Water/Fairy 0.00 0.00 0.00 1
Water/Fighting 0.00 0.00 0.00 1
Water/Flying 0.00 0.00 0.00 1
Water/Ghost 0.00 0.00 0.00 1
Water/Grass 1.00 1.00 1.00 1
Water/Ground 0.00 0.00 0.00 2
Water/Ice 0.00 0.00 0.00 1
Water/Poison 0.00 0.00 0.00 1
Water/Psychic 0.00 0.00 0.00 1
Water/Rock 1.00 1.00 1.00 1
micro avg 0.56 0.56 0.56 200
macro avg 0.34 0.37 0.35 200
weighted avg 0.45 0.56 0.48 200
Kappa (RF): 0.542571992930658
/Users/rohanhangal/PersonalProjects/data_engineering/pokemon_project/venv/lib/python3.13/site-packages/sklearn/metrics/_classification.py:1565: UndefinedMetricWarning: Precision is ill-defined and being set to 0.0 in labels with no predicted samples. Use `zero_division` parameter to control this behavior.
_warn_prf(average, modifier, f"{metric.capitalize()} is", len(result))
/Users/rohanhangal/PersonalProjects/data_engineering/pokemon_project/venv/lib/python3.13/site-packages/sklearn/metrics/_classification.py:1565: UndefinedMetricWarning: Precision is ill-defined and being set to 0.0 in labels with no predicted samples. Use `zero_division` parameter to control this behavior.
_warn_prf(average, modifier, f"{metric.capitalize()} is", len(result))
/Users/rohanhangal/PersonalProjects/data_engineering/pokemon_project/venv/lib/python3.13/site-packages/sklearn/metrics/_classification.py:1565: UndefinedMetricWarning: Precision is ill-defined and being set to 0.0 in labels with no predicted samples. Use `zero_division` parameter to control this behavior.
_warn_prf(average, modifier, f"{metric.capitalize()} is", len(result))